Safari 10.0 で CSS Font Loading Module Level 3 を試してみた
CSS Font Loading Module Level 3
こんにちは、UI デザイナーの清田です。 Safari 10.0 から Webフォントのローディング仕様の CSS Font Loading Module Level 3 が使えるようになったよーとのことで試してみたいと思います。
Text Features
Font Loading
- Web developers can use the CSS Font Loading Module Level 3 specification to create and load font faces from a script and track the loading status of fonts.
- Web fonts are downloaded only if the characters of the rendered text are within the font's Unicode range.
引用 : What's New in Safari
CSS Font Loading Module Level 3 とは?
この仕様は、 CSS 内の font face に対するインタフェースを定義して,font face をスクリプトから容易に作成する/load することを可能にする。 それはまた、ページに利用されている[ 個々の font / すべての font ]の loading 状態°( “status” )を追跡するためのメソッドも提供する。
引用 : CSS Font Loading Module Level 3
なぜ読込仕様が必要なのか?
FOUT という現象をご存知でしょうか?
Flash of Unstyled Text の略称なのですが、Webフォントが指定されているサイトで、サイトをレンダリングする際に、一瞬フォントスタイルが適応されていないフォントが描画されロード完了後にWebフォントが描画される現象を指して呼ばれているとのこと。
参考サイト
- FOUT
試してみる
それでは実際にSafari 10.0 ブラウザ で CSS Font Loading Module Level 3 の動作検証を行ってみます。
Web フォントの読み込み
まずはWeb Fontを読み込むための指定をしてみたいと思います。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>Safari 10.0 - CSS Font Loading Module Level 3</title> <link href="https://fonts.googleapis.com/css?family=Noto+Sans" rel="stylesheet"> </head> <body> <article> <h1>Safari 10.0 - CSS Font Loading Module Level 3</h1> <div id="exampleFontFace"> CSS Font Loading Module Level 3 </div> </article> </body> </html>
document.fonts オブジェクト
CSS Font Loading 仕様が実装されているブラウザの場合、document.fonts オブジェクト確認ができるとのこと。 試しに以下の変数をSafari 9 、Safari 10.0 のブラウザで確認してみました。
<script> var fonts = document.fonts; console.log(fonts) </script>
Safari 9 の場合
ブラウザ側がまだ未対応のため、undefined
が返ってきました。
Safari 10.0 の場合
今回は、FontFaceSet
が返されてきました! Safari 10.0からdocument.fonts
にアクセスできることが確認できました。
document.fonts イベントハンドラーについて
Event handler | Event handler event type |
---|---|
onloading | loading |
onloadingdone | loadingdone |
onloadingerror | loadingerror |
CSS Font Loading Module Level 3
上記、サイトにイベントハンドラーに関する情報が記載されていますが、残念ながらSafari 10.0では正常に動作してくれませんでした。
ちなみに、Chrome側では以下のイベントが正常に実行されました。。。
document.fonts.addEventListener('loading', function() { console.log("フォントの読み込み"); });
document.fonts.addEventListener('loadingerror', function() { console.log("フォントの読み込み失敗"); });
document.fonts.addEventListener('loadingdone', function() { console.log("フォントの読み込み完了"); });
document.fonts メソッドについて
document.fonts
には以下のメソッドが定義されているとのこと
document.fonts.load()
指定したフォント読み込むことが可能なメソッド。読み込み完了後スタイル適応等の操作もできるみたいです。
var f = new FontFace("newfont", "url(newfont.woff)", {}); f.load.then(function (loadedFace) { document.fonts.add(loadedFace); document.body.style.fontFamily = "newfont, serif"; });
document.fonts.ready()
CSS側等で指定した外部のWebフォントが読み込みが完了後実行されるメソッド
document.fonts.ready.then(function(fontFaceSet) { // 引数 に document.fonts がわたされる // 読み込まれた時の処理を記述 console.log("document.fonts.ready"); });
document.fonts.check()
指定したフォントが読み込まれたか判定ができるメソッド
document.fonts.ready.then(function(fontFaceSet) { // 指定したフォントが読み込まれたか確認 console.log(fontFaceSet.check("4rem Monoton")); // 戻り値は true or false });
検証
それでは実際に、javascript側でwebフォントを読み込みとスタイル適応を行って見たいと思います。
Html
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>Safari 10.0 - CSS Font Loading Module Level 3</title> </head> <body> <article> <h1>Safari 10.0 - CSS Font Loading Module Level 3</h1> <div id="exampleFontFace"> CSS Font Loading Module Level 3 </div> </article> <script> var fontFace = new FontFace( "Monoton", "url(https://fonts.gstatic.com/s/monoton/v6/au96iQ3WM1J9H5fMga5i0QLUuEpTyoUstqEm5AMlJo4.woff2)", {} ); fontFace.load().then(function (loadedFace) { document.fonts.add(loadedFace); var element = document.getElementById("exampleFontFace"); element.style.fontFamily = "Monoton, cursive"; element.style.fontSize = "4rem"; }); document.fonts.ready.then(function(fontFaceSet) { // 指定したフォントが読み込まれたか確認 console.log(fontFaceSet.check("4rem Monoton")); }); </script> </body> </html>
実際にブラウザ表示
ブラウザ上でもWebフォントが適応された状態でレンダリングされました。
開発者ツール
読み込みの判定とフォントデータも取得できてました。
まとめ
Choremブラウザ側では既に実装されていた CSS Font Loading Module Level 3ですが、やっとSafari ブラウザ側でも対応してくれました。(まだ対応しきれていない部分もありますが、、、)。Javascript側で制御できるようになったことで、いろいろと表現の幅が広がりそうですね!